home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 2
/
United Public Domain Gold 2.iso
/
utilities
/
pu722.dms
/
pu722.adf
/
60Hz.Asm
< prev
next >
Wrap
Assembly Source File
|
1994-03-20
|
25KB
|
1,029 lines
* SOS *
;========================================================================
;60Hz emulator (PAL-NTSC) V1.04 by P. de Boer in 1991
;
;The program was inspired by Power Utility from Amicon and
;BootPAL/BootNTSC by Nico Francois. Thanks !
;
;my monitor synchronizes from 47.5Hz to 65Hz
;when VBI frequency is 55Hz then the monitor switches.
;
;========================================================================
;Options:
;Press : <LEFT-ALT>+<LEFT-SHIFT>+<CTRL> and :
;
; ESC - To kill the emulator
; 1 - Toggle color bar
; 2 - ?
; 3 - Add ± one line to timer buffer
; 4 - Sub ± one line to timer buffer
; 5 - Add one line to total of rasterlines (decreases VBI frequenzy)
; 6 - Sub one line from total of rasterlines (increases VBI frequenzy)
; 7 - Add one line to end of display
; 8 - Sub one line from end of display
; 9 - Default values
; 0 - Toggle between 50Hz and 60Hz
;
;========================================================================
;Now some stuff we need !
;========================================================================
RSRESET ;little structure for my flags
Flag_60Hz RS.B 1
Flag_Color RS.B 1
Flag_OverScan RS.B 1
Flag_Timing RS.B 1
Flag_Enable RS.B 1
Flag_FatAgnus RS.B 1
Flag_Resident RS.B 1
NULL EQU 0
is_data EQU 14 ;some stuff from the system's include
is_code EQU 18 ;files
gb_DisplayFlags EQU 206 ;graphics
gb_DisplayRows EQU 212
gb_NormalDisplayRows EQU 216
VBlankFrequency EQU 530
_LVODisplayAlert EQU -90 ;intuition
_LVOOpen EQU -30 ;dos
_LVOClose EQU -36
_LVORead EQU -42
_LVOWrite EQU -48
_LVOInput EQU -54
_LVOOutput EQU -60
MODE_OLD EQU 1005 ;dos
MODE_NEW EQU 1006
PR_CLI EQU $AC
PR_MSGPORT EQU $5C
_LVOAlert EQU -108 ;exec
_LVODisable EQU -120
_LVOEnable EQU -126
_LVOForbid EQU -132
_LVOPermit EQU -138
_LVOAddIntServer EQU -168
_LVORemIntServer EQU -174
_LVOAllocMem EQU -198
_LVOFreeMem EQU -210
_LVOAddPort EQU -354
_LVORemPort EQU -360
_LVOPutMsg EQU -366
_LVOGetMsg EQU -372
_LVOFindPort EQU -390
_LVOCloseLibrary EQU -414
_LVOSumLibrary EQU -426
_LVOOpenResource EQU -498
_LVOOpenLibrary EQU -552
_LVOSumKickData EQU -612
_LVOCopyMem EQU -624
ExecBase EQU $4
LIBF_CHANGED EQU 2
LIB_FLAGS EQU 14
RSRESET ;node structure
LN RS.B 0
LN_SUCC RS.L 1
LN_PRED RS.L 1
LN_TYPE RS.B 1
LN_PRI RS.B 1
LN_NAME RS.L 1
LN_SIZE RS.W 0
NT_MSGPORT EQU 4
NT_MESSAGE EQU 5
RSRESET ;memlist structure
ML RS.B LN_SIZE
ML_NUMENTRIES RS.W 1
ML_ME RS.W 0
ML_SIZE RS.W 0
RSRESET
ME RS.B 0
ME_REQS RS.W 0
ME_ADDR RS.L 1
ME_LENGTH RS.L 1
ME_SIZE RS.W 0
MEMF_PUBLIC EQU 1<<0
MEMF_CHIP EQU 1<<1
RSRESET ;resident structure
RT RS.B 0
RT_MATCHWORD RS.W 1
RT_MATCHTAG RS.L 1
RT_ENDSKIP RS.L 1
RT_FLAGS RS.B 1
RT_VERSION RS.B 1
RT_TYPE RS.B 1
RT_PRI RS.B 1
RT_NAME RS.L 1
RT_IDSTRING RS.L 1
RT_INIT RS.L 1
RT_SIZE RS.W 0
RTC_MATCHWORD EQU $4AFC
RTB_COLDSTART EQU 0
RTF_COLDSTART EQU 1<<0
RTB_AUTOINIT EQU 7
RTF_AUTOINIT EQU 1<<7
RTM_WHEN EQU 1
RTW_NEVER EQU 0
RTW_COLDSTART EQU 1
KickMemPtr EQU 546 ;execbase equ's
KickTagPtr EQU 550
KickCheckSum EQU 554
DMACONR EQU $002 ;custom chip addresses
VPOSR EQU $004
VHPOSR EQU $006
VPOSW EQU $02A
VHPOSW EQU $02C
DIWSTRT EQU $08E
DIWSTOP EQU $090
DMACON EQU $096
COLOR00 EQU $180
BEAMCON0 EQU $1DC
CUSTOM EQU $DFF000
;========================================================================
CALL MACRO
IFC 'EXEC','\1'
MOVEA.L (ExecBase).W,A6
ENDC
IFNC 'EXEC','\1'
MOVEA.L \1Base,A6
ENDC
JSR _LVO\2(A6)
ENDM
OPENLIB MACRO
LEA \1Name(PC),A1
CLR.L D0
CALL EXEC,OpenLibrary
MOVE.L D0,\1Base
BEQ \2
ENDM
CLOSELIB MACRO
MOVEA.L \1Base,A1
CALL EXEC,CloseLibrary
ENDM
;========================================================================
;Here we go !!!
;========================================================================
InstallEmulator move.l a0,a5 ;store pointer to cmd line
st Flag_Resident+Flags
;===============================================
CheckAgnus move.w $DFF004,d0 ;check what kind of agnus
and.w #$2000,d0 ;we got
beq.s OldAgnus
st Flag_FatAgnus+Flags
OldAgnus
;===============================================
OpenDosLib OPENLIB DOS,NoDOS ;open dos library
CALL DOS,Output ;get standart output chanel
move.l d0,OutHandle ;store it
beq.s .Skip ;if not available then skip
move.l OutHandle(pc),d1
move.l #Hello.TXT,d2
move.l #Hello.LEN,d3
CALL DOS,Write ;print message
.Skip
;===============================================
SearchFlagOpt movea.l a5,a0 ;search for any flag options
.SearchLoop move.b (a0)+,d0
cmp.b #$0A,d0 ;jump out of loop if we
beq.s Search ;find a return
cmp.b #"?",d0 ;an request for info ?
beq.s .PrintSyntax
ori.b #$20,d0 ;make lower case (quick &dirty)
cmp.b #"a",d0 ;ignore BIG-FAT-Agnus ?
beq.s .OverRide
cmp.b #"r",d0 ;non resident install ?
bne.s .SearchLoop
.Resident SF Flag_Resident+Flags ;clear Resident flag
bra.s .SearchLoop
.OverRide SF Flag_FatAgnus+Flags ;clear FAT agnus flag
bra.s .SearchLoop
.PrintSyntax move.l #Syntax.TXT,d2 ;Print syntax if we've found
move.l #Syntax.LEN,d3 ;an '?'
bra PrintMsgAndQuit
;===============================================
Search movea.l a5,a0 ;search for install options
.SearchLoop move.b (a0),d0
cmp.b #"i",d0
beq.w InstallNTSC
cmp.b #"I",d0
beq.w InstallPAL
ori.b #$20,d0 ;always lower case
cmp.b #"k",d0
beq.s Remove
cmp.b #$0A,(a0)+
bne.s .SearchLoop
bra.s InstallNTSC
;===============================================
Remove lea MyPortName(PC),a1 ;search emulator msg.port
CALL EXEC,FindPort ;find my port
tst.l d0
bne.s FoundMyPort
move.l #Unable.TXT,d2 ;can't find port !
move.l #Unable.LEN,d3
bra.w PrintMsgAndQuit
FoundMyPort move.l d0,a0 ;found port
lea Message(pc),a1 ;send message to emulator
move.l #'KILL',20(a5) ;kill MSG
CALL EXEC,PutMsg ;to remove itself.
Waitting cmp.l #'KILL',Message.TXT ;waiting for return msg
beq.s Waitting
tst.l Message.TXT ;message = 0 ??
bne.s .Error ;no -> something wrong
.Killed move.l #Removed.TXT,d2 ;all well, print remove
move.l #Removed.LEN,d3 ;message
bra.w PrintMsgAndQuit
.Error move.l #Unable.TXT,d2 ;no -> something went
move.l #Unable.LEN,d3 ;wrong
bra.w PrintMsgAndQuit
;===============================================
InstallNTSC sf Flag_60Hz+Flags ;install and start NTSC
bra.s Install
InstallPAL st Flag_60Hz+Flags ;install and Start PAL
Install BSR InstallRomTag ;install Tag
bne.s PrintMsgAndQuit
;===============================================
TagInstalled jsr 4(a0) ;Initialize emulator
beq.s EmulatorOn
BSR RemoveRomTag ;kill romtag if something wrong
move.l #Failure.TXT,d2
move.l #Failure.LEN,d3
bra.s PrintMsgAndQuit
EmulatorOn tst.b Flag_FatAgnus+Flags
beq.s .Skip
move.l #NewAgnus.TXT,d2
move.l #NewAgnus.LEN,d3
move.l OutHandle(pc),d1
beq.s .Skip
CALL DOS,Write ;print agnus message
.Skip tst.b Flag_Resident+Flags
bne.s .Skip2
move.l #NResident.TXT,d2
move.l #NResident.LEN,d3
move.l OutHandle(pc),d1
beq.s .Skip2
CALL DOS,Write ;print resident message
.Skip2 move.l #Installed.TXT,d2
move.l #Installed.LEN,d3
;===============================================
PrintMsgAndQuit move.l OutHandle(pc),d1
beq.s Einde
CALL DOS,Write ;print message
Einde CLOSELIB DOS ;close dos library
NoDOS clr.l d0
rts
;========================================================================
Message DC.L 0 ;message to emulator
DC.L 0
DC.B NT_MESSAGE
DC.B 0
DC.L 0
DC.L 0 ;reply port: geen
DC.W Message.LEN
Message.TXT DC.B "KILL"
Message.LEN EQU *-Message.TXT
DOSName DC.B "dos.library",$0
EVEN
DOSBase DC.L 0
CodeMem DC.L 0
OutHandle DC.L 0
Hello.TXT DC.B $9B,"33;1m60Hz Emulator"
DC.B $9B,"0m V1.04 by P. de Boer",$0A
Hello.LEN EQU *-Hello.TXT
Syntax.TXT DC.B "This program is shareware, NOT public domain !"
DC.B $0A
DC.B "Read the .DOC file for more information !"
DC.B $0A,$0A
DC.B $9B,"1;33mSyntax....:"
DC.B $9B,"0m 60Hz <OPTIONS>",$0A
DC.B $9B,"1;33mOptions...:",$9B,"0m "
DC.B "i = Install emulator and jump in NTSC mode.",$0A
DC.B " "
DC.B "I = Install emulator and jump in PAL mode.",$0A
DC.B " "
DC.B "K/k = Kill emulator !",$0A
DC.B $9B,"1;33mAdditional:",$9B,"0m "
DC.B "R/r = Install emulator NON-resident in memory",$0A
DC.B " "
DC.B "A/a = Ignore BIG FAT-Agnus, i.e. always software"
DC.B " emulation",$0A,$0A
DC.B "When the emulator is installed, ",$0A
DC.B "press <LEFT-ALT>+<LEFT-SHIFT>+<CTRL> and ",$0A
DC.B "ESC - To remove the emulator from memory",$0A
DC.B " 0 - To toggle between PAL and NTSC",$0A,$0A
Syntax.LEN EQU *-Syntax.TXT
Already.TXT DC.B "60Hz Emulator was already installed !",$0A
Already.LEN EQU *-Already.TXT
NoMem.TXT DC.B "Not enough memory for emulator (I only need "
DC.B "±2800 Bytes) !",$0A
NoMem.LEN EQU *-NoMem.TXT
Installed.TXT DC.B "60Hz Emulator installed !",$0A
Installed.LEN EQU *-Installed.TXT
Removed.TXT DC.B "60Hz Emulator removed !",$0A
Removed.LEN EQU *-Removed.TXT
Unable.TXT DC.B "Unable to find Emulator in memory !",$0A
Unable.LEN EQU *-Unable.TXT
Failure.TXT DC.B "Installation failed !",$0A
Failure.LEN EQU *-Failure.TXT
NewAgnus.TXT DC.B "Fantastic, you got a BIG FAT-Agnus !!",$0A
NewAgnus.LEN EQU *-NewAgnus.TXT
NResident.TXT DC.B "Emulator will be gone after reset !",$0A
NResident.LEN EQU *-NResident.TXT
EVEN
;========================================================================
InstallRomTag lea MyPortName(PC),a1 ;find my port
CALL EXEC,FindPort
tst.l d0
beq.s AllocateMem
move.l #Already.TXT,d2 ;already installed
moveq #Already.LEN,d3
moveq #-1,d0
rts
AllocateMem move.l #TagCodeLen,d0 ;allocate memory for
moveq #MEMF_CHIP,d1 ;emulator
CALL EXEC,AllocMem
tst.l d0
bne.s CopyTagCode
move.l #NoMem.TXT,d2 ;not enough memory ??
moveq #NoMem.LEN,d3
moveq #-1,d0
rts
CopyTagCode movea.l d0,a5 ;a5 holds address of copy
lea TagCode(PC),a0 ;copy code
movea.l d0,a1
move.l #TagCodeLen,d0
CALL EXEC,CopyMem
lea Flags(pc),a0
tst.b Flag_Resident(a0)
beq.s InitPort
CALL EXEC,Forbid ;shut down system
CALL EXEC,Disable
lea RomTagPtrs-TagCode(a5),a0
move.l KickTagPtr(a6),4(a0)
beq.s NoTagYet
bset #7,4(a0) ;set bit 31 if tag was set
NoTagYet move.l a0,KickTagPtr(a6) ;install my romtag
lea MyRomTag-TagCode(a5),a1
move.l a1,(a0)
InitMemList lea MyMemList-TagCode(a5),a1
move.l a5,ML_SIZE+ME_ADDR(a1)
move.l KickMemPtr(a6),d0
move.l d0,LN_SUCC(a1)
move.l a1,KickMemPtr(a6) ;install my memlist
InitRomTag lea MyRomTag-TagCode(a5),a1
move.l a1,RT_MATCHTAG(a1)
lea RT_SIZE(a1),a2
move.l a2,RT_ENDSKIP(a1)
lea ProjectName-TagCode(a5),a2
move.l a2,RT_NAME(a1)
move.l a5,RT_INIT(a1)
CALL EXEC,SumKickData
move.l d0,KickCheckSum(a6) ;recalculate checksum
InitPort lea MyPortName-TagCode(a5),a0
lea MyPort-TagCode(a5),a1
clr.l LN_SUCC(a1)
clr.l LN_PRED(a1)
move.l a0,LN_NAME(a1)
CALL EXEC,AddPort ;add my port
CALL EXEC,Enable ;powerup system
CALL EXEC,Permit
Exit movea.l a5,a0 ;pass code address
clr.l d0
rts
;========================================================================
;This piece of code will be resident in memory !
;========================================================================
TagCode JMP InitTagCode(pc) ;jump table
JMP InitEmulator(pc)
;========================================================================
InitTagCode movem.l d0-d7/a0-a6,-(SP) ;this routine
;will be executed
lea MyPort(pc),a1 ;in the reset routine
lea MyPortName(PC),a0
clr.l LN_SUCC(a1)
clr.l LN_PRED(a1)
move.l a0,LN_NAME(a1)
CALL EXEC,AddPort
BSR.S InitEmulator ;re-init emulator
EndTagCode movem.l (SP)+,d0-d7/a0-a6 ;return to kicky
rts
;========================================================================
InitEmulator BSR.S InitStructures
lea Flags(pc),a0
sf Flag_Enable(a0) ;prevent interrupt
tst.b Flag_FatAgnus(a0)
bne.s .Skip
BSR.S OpenIntLib
BSR.S OpenResource
BNE.S .Failure
.Skip BSR PatchSystem
BNE.S .Failure
BSR AddServers
clr.l d0
.Failure rts
;========================================================================
Alert clr.l d0 ;display alert
moveq #32,d1
movea.l INTBase(pc),a6
jsr _LVODisplayAlert(a6)
rts
;===============================================
OpenIntLib lea INTName(pc),a1
clr.l d0
CALL EXEC,OpenLibrary
lea INTBase(pc),a0
move.l d0,(a0)
bne.s .Skip
rts
move.l #$04030000,d7 ;software failure
lea $FC00D2,a5 ;if intuition.library
CALL EXEC,Alert ;didn't open
.Skip rts
;===============================================
InitStructures lea TagCode(pc),a0 ;relocate structures !
move.l a0,d0
lea CIAA_Server(pc),a0
BSR.S .InitStruct
lea CIAB_Server(pc),a0
BSR.S .InitStruct
lea VBI_Server(pc),a0
.InitStruct add.l d0,LN_NAME(a0)
add.l d0,is_data(a0)
add.l d0,is_code(a0)
lea InitStructures(pc),a0
move.w #$4E75,(a0) ;put RTS at InitStruct
rts
;===============================================
OpenResource lea CIABName(pc),a1 ;open ciab.resource
clr.l d0
CALL EXEC,OpenResource
lea CIABBase(pc),a0
move.l d0,(a0)
beq.s .Error
moveq #0,d0
rts
.Error lea NoResourceAlert(pc),a0 ;no resource ??
BSR.W Alert
moveq #-1,d0
rts
;===============================================
AllocateTimer move.b #0,d0 ;timer a interrupt
lea CIAB_Server(pc),a1
move.l CIABBase(pc),a6
jsr -6(a6) ;set interrupt
tst.l d0
beq.s .Ok
.Error lea NoTimerAlert(pc),a0 ;no timer !
BSR.W Alert
moveq #-1,d0
.Ok rts
;===============================================
DeAllocateTimer move.b #0,d0
move.l CIABBase(pc),a6
jsr -12(a6) ;clr interrupt
rts
;===============================================
AddServers lea Flags(pc),a0
sf Flag_Enable(a0)
move.w #$0005,d0 ;vertical blank interrupt
lea VBI_Server(pc),a1
CALL EXEC,AddIntServer
move.w #$0003,d0 ;keyboard interrupt
lea CIAA_Server(pc),a1
CALL EXEC,AddIntServer
lea Flags(pc),a0
st Flag_Enable(a0)
rts
;===============================================
PatchSystem lea Flags(pc),a0 ;this routine does it !
tst.b Flag_60Hz(a0)
beq.s Go60
;===============================================
Go50 tst.b Flag_FatAgnus(a0) ;put system in PAL mode
beq.s .NoFatty
move.w #$0020,BEAMCON0!CUSTOM ;very simple if we have a FAT
bra.s .Go50 ;Agnus
.NoFatty BSR.S DeAllocateTimer ;free timers
.Go50 lea Flags(pc),a0
sf Flag_Enable(a0) ;stop it
lea GFXName(PC),a1
clr.l d0
CALL EXEC,OpenLibrary ;open graphics library
move.l d0,a1
move.w gb_DisplayFlags(a1),d0 ;adjust display flags
and.b #%11111110,d0 ;erase NTSC flag
or.b #%00000100,d0 ;set PAL flag
move.w d0,gb_DisplayFlags(a1)
move.w #256,gb_NormalDisplayRows(a1)
move.w #311,gb_DisplayRows(a1)
or.b #LIBF_CHANGED,LIB_FLAGS(a1)
movea.l a1,a2
CALL EXEC,SumLibrary ;caluclate checksum
movea.l a2,a1
CALL EXEC,CloseLibrary ;close lib again
move.b #50,VBlankFrequency(a6) ;change EXEC library
or.b #LIBF_CHANGED,LIB_FLAGS(a6)
CALL EXEC,SumLibrary ;calculate checksum
moveq #0,d0
rts
;===============================================
Go60 tst.b Flag_FatAgnus(a0) ;put system in NTSC mode
beq.s .NoFatty
move.w #$0000,BEAMCON0!CUSTOM ;to NTSC please
bra.s .Go60
.NoFatty BSR AllocateTimer ;allocate timers again
bne.s .Error ;not available
.Go60 lea GFXName(PC),a1 ;modify graphics.library
clr.l d0
CALL EXEC,OpenLibrary
move.l d0,a1
move.w gb_DisplayFlags(a1),d0
and.b #%11111011,d0
or.b #%00000001,d0
move.w d0,gb_DisplayFlags(a1)
move.w #200,gb_NormalDisplayRows(a1)
move.w #262,gb_DisplayRows(a1)
or.b #LIBF_CHANGED,LIB_FLAGS(a1)
movea.l a1,a2
CALL EXEC,SumLibrary
movea.l a2,a1
CALL EXEC,CloseLibrary
move.b #60,VBlankFrequency(a6)
or.b #LIBF_CHANGED,LIB_FLAGS(a6)
CALL EXEC,SumLibrary
lea Flags(pc),a0
st Flag_Enable(a0) ;start it
moveq #0,d0
rts
.Error lea Flags(pc),a0
st Flag_60Hz(a0)
sf Flag_Enable(a0) ;stop it
moveq #-1,d0
rts
;========================================================================
CIAA_Server_Int movem.l d0-d7/a0-a6,-(SP) ;keyboard interrupt
st d1 ;server
lea EnterKeys(pc),a0
move.b $BFEC01,d5 ;read raw keycode
not.b d5
ror.b #1,d5
bmi.s .NotPressed
sf d1
.NotPressed andi.b #$7F,d5
.TestCTRL cmp.b #$63,d5
bne.s .TestSHIFT
move.b d1,(a0)
.TestSHIFT cmp.b #$60,d5
bne.s .TestALT
move.b d1,1(a0)
.TestALT cmp.b #$64,d5
bne.s .EndTest
move.b d1,2(a0)
.EndTest tst.b d1
bne.s CIAA_Return
AreWeInControl tst.l (a0)
bne.s CIAA_Return
cmp.b #$45,d5
beq.s .Go
cmp.b #$0A,d5
bgt.s CIAA_Return
.Go clr.b $BFEC01 ;kill key-code
lea Flags(pc),a5
BSR CheckESC
tst.b Flag_Enable(a5)
beq.s .Skip
BSR CheckColor ;check keys
BSR CheckTiming
BSR CheckTime
BSR CheckStartPos
BSR CheckEndPos
BSR CheckDefault
.Skip BSR Check60Hz
CIAA_Return movem.l (SP)+,d0-d7/a0-a6
DC.W $003C,$0004
rts
;========================================================================
VBI_Server_Int movem.l d0-d7/a0-a6,-(SP) ;vertical blank interrupt
BSR CheckForMSG ;check for incoming msg
lea Flags(pc),a0 ;server
tst.b Flag_Enable(a0) ;are we in 60Hz mode ?
beq.s .Skip ;if not then skip
lea CUSTOM,a0 ;custom chip base
move.w DMACONR(a0),d1 ;read DMACON
move.w #$0440,DMACON(a0) ;clear blitpri & blitdma
clr.w d0
move.b VHPOSR(a0),d0 ;read actual beam pos
neg.w d0 ;make it negative
add.w EndPos(pc),d0 ;add endpos
mulu #45,d0 ;multiply with cycle/line
sub.w VBITime(pc),d0 ;subtrack buffer time
move.b d0,$bfd400 ; Timer A high byte
lsr.w #8,d0 ;get low byte
move.b d0,$bfd500 ; Timer A low byte
move.b #%00011001,$BFDE00 ;load timer-a
andi.w #$0440,d1 ;reinstall dma again
ori.w #$8000,d1
move.w d1,DMACON(a0) ;write it in dmacon
.Skip movem.l (SP)+,d0-d7/a0-a6
DC.W $003C,$0004 ;or.w #$4,SR ;set Z-Flag
rts
;========================================================================
CIAB_Server_Int movem.l d0-d2/a0,-(a7)
lea Flags(pc),a0
tst.b Flag_Enable(a0)
beq.s GetOutOfHere
lea CUSTOM,a0 ;get custom base address
move.w DMACONR(a0),d2 ;read dma
move.w #$0440,DMACON(a0) ;clear blitpri&blitdma
move.w EndPos(pc),d1
lsl.w #8,d1
ori.w #$D1,d1
StartColor move.w #$0505,$1FE(a0) ;put colorbar if needed
move.w EndPos(pc),d0 ;wait for line 'EndPos'
WaitLine cmp.b VHPOSR(a0),d0
bgt.s WaitLine
move.w d1,DIWSTOP(a0)
EndColor move.w #$0000,$1FE(a0)
move.l StartPos(pc),d1
move.l VPOSR(a0),d0 ;prevents shocking
sub.l VPOSR(a0),d0 ;of menu bar
sub.l d0,d1 ;subtract it from StartPos
add.l VPOSR(a0),d1 ;add current beam pos
move.l d1,VPOSW(a0) ;write new beampos
andi.w #$0440,d2 ;
ori.w #$8000,d2
move.w d2,DMACON(a0) ;enable blitpri&blitdma
GetOutOfHere movem.l (a7)+,d0-d2/a0 ;return to system
rts
;========================================================================
CheckForMSG lea MyPort(pc),a0 ;check message port
CALL EXEC,GetMsg ;get message
tst.l d0
beq.s .NoMSG ;mmmm.. no message
move.l d0,a5 ;got message, yeah !
cmp.l #"KILL",20(a5) ;is it a 'KILL' message ??
beq.s MSG.Kill
cmp.l #"50Hz",20(a5)
beq.s MSG.50Hz
cmp.l #"60Hz",20(a5)
beq.s MSG.60Hz
.NoMSG rts
MSG.50Hz lea Flags(pc),a0
tst.b Flag_60Hz(a0)
bne.s .Already50Hz
st Flag_60Hz(a0)
BSR.W PatchSystem
.Already50Hz clr.l 20(a5)
rts
MSG.60Hz lea Flags(pc),a0
tst.b Flag_60Hz(a0)
beq.s .Already60Hz
sf Flag_60Hz(a0)
BSR PatchSystem
move.l d0,20(a5)
rts
.Already60Hz clr.l 20(a5)
rts
MSG.Kill BSR KillEmulator ;yes? -> kill me (?)
move.l d0,20(a5)
rts
;========================================================================
;Subroutines for key checking !
;
;=======================================
CheckColor cmp.b #$01,d5
bne.s .NoColorFlag
lea EndColor+4(pc),a1
lea StartColor+4(pc),a2
not.b Flag_Color(a5)
beq.s .ColorOff
.ColorOn move.w #COLOR00,(a1)
move.w #COLOR00,(a2)
bra.s .NoColorFlag
.ColorOff move.w #$01FE,(a1)
move.w #$01FE,(a2)
.NoColorFlag rts
;=======================================
CheckTiming cmp.b #$02,d5
bne.s .NoTimingCheck
not.b Flag_Timing(a5)
.NoTimingCheck rts
;=======================================
CheckTime lea VBITime(pc),a1
cmp.b #$03,d5
beq.s .NoAdd
sub.w #45,(a1)
.NoAdd cmp.b #$04,d5
beq.s .NoSub
add.w #45,(a1)
.NoSub rts
;=======================================
CheckStartPos lea StartPos(pc),a1
cmp.b #$05,d5
beq.s .NoAdd
add.l #$0100,(a1)
.NoAdd cmp.b #$06,d5
beq.s .NoSub
sub.l #$0100,(a1)
.NoSub rts
;=======================================
CheckEndPos lea EndPos(pc),a1
cmp.b #$07,d5
beq.s .NoAdd
addq.w #$0001,(a1)
.NoAdd cmp.b #$08,d5
beq.s .NoSub
subq.w #$0001,(a1)
.NoSub rts
;=======================================
CheckDefault cmp.b #$09,d5
bne.s .Skip
lea EndPos(pc),a1
move.w #$0104,(a1)
lea StartPos(pc),a1
move.l #$3203,(a1)
lea VBITime(pc),a1
move.w #8*45,(a1)
.Skip rts
;=======================================
Check60Hz cmp.b #$0A,d5
bne.s .Skip
not.b Flag_60Hz(a5)
BSR PatchSystem
.Skip rts
;=======================================
CheckESC cmp.b #$45,d5
bne.s .Skip
BSR.S KillEmulator
.Skip rts
;========================================================================
KillEmulator CALL EXEC,Disable
move.w #$0005,d0 ;vertical blank interrupt
lea VBI_Server(pc),a1
CALL EXEC,RemIntServer
move.w #$0003,d0 ;keyboard interrupt
lea CIAA_Server(pc),a1
CALL EXEC,RemIntServer
lea Flags(pc),a0
st Flag_60Hz(a0)
BSR PatchSystem
BSR.S RemoveRomTag
move.l d0,d2
CALL EXEC,Enable
rts
;========================================================================
RemoveRomTag lea MyPortName(PC),a1
CALL EXEC,FindPort ;find my port
tst.l d0
bne.s FoundPort
moveq #-1,d0 ;no port found ??
rts
FoundPort move.l d0,a4 ;a4 = pointer to MyPort
move.l a4,a1
CALL EXEC,RemPort ;remove it !
lea Flags(pc),a0
tst.b Flag_Resident(a0)
beq.s FreeMemory
CALL EXEC,Forbid ;shut down system
CALL EXEC,Disable
lea MyMemList-MyPort(a4),a1 ;find my memlist
lea KickMemPtr(a6),a0
FindMyMemList move.l LN_SUCC(a0),d0
cmp.l d0,a1
beq.s FoundMyList
move.l d0,a0
bra.s FindMyMemList
FoundMyList move.l LN_SUCC(a1),d0 ;clear memlist from system
move.l d0,LN_SUCC(a0) ; LN_SUCC = 0, so this also
; works for KickMemPtr
move.l RomTagPtrs-MyPort+4(a4),KickTagPtr(a6)
beq.s NoSecondTag
bclr #7,KickTagPtr(a6) ;clear bit 31
NoSecondTag CALL EXEC,SumKickData
tst.l KickTagPtr(a6) ;check if one of the
bne.s .Set ;ptrs is set
tst.l KickMemPtr(a6) ;if so, then no need
bne.s .Set ;to calc checksum
clr.l d0 ;so, clear it !
.Set move.l d0,KickCheckSum(a6) ;restore old
CALL EXEC,Enable ;power up system
CALL EXEC,Permit
FreeMemory lea TagCode-MyPort(a4),a1 ;free tag memory
move.l #TagCodeLen,d0
CALL EXEC,FreeMem
clr.l d0
rts
;========================================================================
CIAA_Server DC.L 0 ;interrupt server structure
DC.L 0
DC.B 2 ;type = interrupt
DC.B 10 ;pri
DC.L ProjectName-TagCode
DC.L CIAA_Server-TagCode
DC.L CIAA_Server_Int-TagCode
CIAB_Server DC.L 0
DC.L 0
DC.B 2 ;type = interrupt
DC.B 10 ;pri
DC.L ProjectName-TagCode
DC.L CIAB_Server-TagCode
DC.L CIAB_Server_Int-TagCode
VBI_Server DC.L 0
DC.L 0
DC.B 2 ;type = interrupt
DC.B 127 ;pri
DC.L ProjectName-TagCode
DC.L VBI_Server-TagCode
DC.L VBI_Server_Int-TagCode
MyMemList DS.B LN_SIZE ;memlist structure
DC.W 1
DC.L NULL
DC.L TagCodeLen
MyPort DC.L NULL ;message port structure
DC.L NULL
DC.B NT_MSGPORT
DC.B 0
DC.L NULL
DC.B 0
DC.B 0
DC.L NULL
DS.B 14
MyRomTag DC.W RTC_MATCHWORD ;resident structure
DC.L NULL
DC.L NULL
DC.B RTF_COLDSTART
DC.B 1
DC.B 0
DC.B -10
DC.L NULL
DC.L NULL
DC.L 0
;========================================================================
ProjectName DC.B "60Hz emulator by P. de Boer",$0
MyPortName DC.B "60Hz emulator.port",$0
EVEN
CIABName DC.B "ciab.resource",$0
INTName DC.B "intuition.library",$0
GFXName DC.B "graphics.library",$0
EVEN
NoTimerAlert DC.W 20
DC.B 17
DC.B "Emulator failure: "
DC.B "CIA-B Timer-A already in use !",$0
EVEN
NoResourceAlert DC.W 20
DC.B 17
DC.B "Emulator failure: "
DC.B "Unable to open ciab.resource !",$0
EVEN
StartPos DC.L $3202 ;Start pos
EndPos DC.W $0104
Flags DCB.B 8
EnterKeys DC.L $FFFFFF00
VBITime DC.W 8*45 ;buffer time (important !)
INTBase DC.L 0
CIABBase DC.L 0
RomTagPtrs DCB.L 2,$0
TagCodeLen EQU *-TagCode
;========================================================================
;|